User guide previous pagenext page

5.3: Dock and undock Go back up one level

When a uiextras.BoxPanel has its "DockFcn" filled in, a dock/undock button ( / ) is shown in the upper-right of the title-bar. When the user clicks this button the specified function is called. Since re-docking the panel into its previous parent depends on the type of parent, it is up to the user to write some code to actually extract or insert the panel.

The following simple example shows how to add dock/undock functionality to a box full of panels. Save the code into a file called "dockexample.m" to run it.

(The code for this example can be found here: [ view | edit | run ] )

Create the layout with three panels

Open a new figure window and add three panels.

function dockexample()
% Create the window and main layout
fig = figure( 'Name', 'Dockable GUI example', ...
              'NumberTitle', 'off', ...
              'Toolbar', 'none', ...
              'MenuBar', 'none', ...
              'CloseRequestFcn', @nCloseAll );
box = uiextras.HBox( 'Parent', fig );

% Add three panels to the box
panel{1} = uiextras.BoxPanel( 'Title', 'Panel 1', 'Parent', box );
panel{2} = uiextras.BoxPanel( 'Title', 'Panel 2', 'Parent', box );
panel{3} = uiextras.BoxPanel( 'Title', 'Panel 3', 'Parent', box );

% Add some contents
uicontrol( 'Style', 'PushButton', 'String', 'Button 1', 'Parent', panel{1} ); uicontrol( 'Style', 'PushButton', 'String', 'Button 2', 'Parent', panel{2} ); uicontrol( 'Style', 'PushButton', 'String', 'Button 3', 'Parent', panel{3} );

Add the dock/undock callback

We set each panel to call the same dock/undock function. This function is nested inside the main function so that it has access to the main function's variables. A better way to do this is to make the main function into a class, but this nested-function approach is fine for simple applications.

Note that as soon as we set the "DockFcn" property the Dock/Undock icon appears in the top-right of each panel. We use a cell-array to pass an extra argument, the panel number, to the minimize function. This extra argument appears after the usual eventSource and eventData arguments.

% Set the dock/undock callback
set( panel{1}, 'DockFcn', {@nDock, 1} ); set( panel{2}, 'DockFcn', {@nDock, 2} ); set( panel{3}, 'DockFcn', {@nDock, 3} ); %-------------------------------------------------------------------------%
function nDock( eventSource, eventData, whichpanel ) % Set the flag panel{whichpanel}.IsDocked = ~panel{whichpanel}.IsDocked; if panel{whichpanel}.IsDocked % Put it back into the layout newfig = get( panel{whichpanel}, 'Parent' ); set( panel{whichpanel}, 'Parent', box ); delete( newfig ); else  % Take it out of the layout pos = getpixelposition( panel{whichpanel} ); newfig = figure( ... 'Name', get( panel{whichpanel}, 'Title' ), ... 'NumberTitle', 'off', ... 'MenuBar', 'none', ... 'Toolbar', 'none', ... 'CloseRequestFcn', {@nDock, whichpanel} ); figpos = get( newfig, 'Position' ); set( newfig, 'Position', [figpos(1,1:2), pos(1,3:4)] ); set( p{whichpanel}, 'Parent', newfig, ... 'Units', 'Normalized', ... 'Position', [0 0 1 1] ); end  end % nDock

Add the close callback

If the user closes the main window we need to also close any other windows that were created. This can be done by finding the window that contains each panel and deleting it.

%-------------------------------------------------------------------------%
function nCloseAll( ~, ~ ) for ii=1:numel( panel ) if isvalid( panel{ii} ) && ~strcmpi( panel{ii}.BeingDeleted, 'on' ) figh = ancestor( panel{ii}, 'figure' ); delete( figh ); end  end  end % nCloseAll end % Main function

Click the dock buttons

Undocking the middle panel causes the other two to fill the vacated space. The undocked panel appears in its own window, with the "Undock" icon replaced by a "Dock" icon.

.

Re-docking the panel would cause it to be appended to the right of the list in the original window. Closing the main window causes all panels, docked or undocked, and their enclosing windows to be closed.


© 2011 The MathWorks Ltd Terms of Use Patents Trademarks